package com.xd.middlesoftware.whitelist;

import com.alibaba.fastjson.JSON;
import com.xd.middlesoftware.whitelist.annotation.DoWhiteList;
import org.apache.commons.beanutils.BeanUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;

/**
 * @className: com.xd.middlesoftware.whitelist-> DojoinPoint
 * @description:
 * @author: lxd
 * @createDate: 2022-01-21 3:48 下午
 * @version: 1.0
 */
@Aspect
@Component
public class DojoinPoint {

    private Logger logger = LoggerFactory.getLogger(DojoinPoint.class);

    @Resource
    private String whiteListConfig;

    /**
     * 切点
     */
    @Pointcut("@annotation(com.xd.middlesoftware.whitelist.annotation.DoWhiteList)")
    public void aopPoint(){
    }

    /**
     * 环绕切面
     * @param jp
     * @return
     * @throws Throwable
     */
    @Around("aopPoint()")
    public Object doRouter(ProceedingJoinPoint jp) throws Throwable {
        //获取内容
         Method method =getMethod(jp);
        DoWhiteList whiteList = method.getAnnotation(DoWhiteList.class);
        //获取字段value
        // 获取字段值
        String keyValue = getFiledValue(whiteList.key(), jp.getArgs());
        //校验过滤
        logger.info("middleware whitelist handler method：{} value：{}", method.getName(), keyValue);
        if (null == keyValue || "".equals(keyValue)) {
            return jp.proceed();
        }

        String[] split = whiteListConfig.split(",");

        for (String str:split){
            if (keyValue.equals(str)) {
                return jp.proceed();
            }
        }
        //拦截返回
        // 拦截
        return returnObject(whiteList, method);
    }

    private Object returnObject(DoWhiteList whiteList, Method method) throws IllegalAccessException, InstantiationException {
        Class<?> returnType = method.getReturnType();
        String returnJson = whiteList.returnJson();
        if ("".equals(returnJson)) {
            return returnType.newInstance();
        }
        return JSON.parseObject(returnJson, returnType);
    }

    /**
     * 获取字段value
     * @param key
     * @param args
     * @return
     */
    private String getFiledValue(String key, Object[] args) {
        String keyValue =null;
        try {
            for (Object obj:args){
                if(keyValue == null || keyValue==""){
                    keyValue = BeanUtils.getProperty(obj,key);
                }else {
                    break;
                }
            }
        }catch (Exception e){
            if (args.length == 1) {
                return args[0].toString();
            }
        }
        return keyValue;
    }

    /**
     * 获取方法
     * @param jp
     * @return
     */
    private Method getMethod(ProceedingJoinPoint jp) throws NoSuchMethodException {
        //获取签名
        Signature signature = jp.getSignature();
        //强转方法签名
        MethodSignature methodSignature = (MethodSignature)signature;
        //获取方法
        return jp.getTarget().getClass().getMethod(methodSignature.getName(),methodSignature.getParameterTypes());
    }


}
